import random

"""
任务1：构建嵌套数据结构
创建以下嵌套容器：
students 列表：包含多个字典，每个字典表示一个学生，格式如下：
python
{
  "id": "S001",
  "name": "张三",
  "age": 20,
  "courses": ["数学", "物理"],  # 课程列表（可能重复）
  "scores": {"数学": 85, "物理": 90}  # 成绩字典
}
all_courses 集合：存储所有课程名称（去重）。
要求：
使用列表推导式生成5个学生数据（ID从S001到S005）。
通过字典推导式统计每门课程的选修人数，结果存入字典course_counts。
"""
# 1我要使用列表推导式生成5个学生，列表的每个元素是一个字典，字典的部分元素是嵌套了别的容器
# courses的值是一个列表
# score的值是一个字典
students = [{"id": x,
             "name": "tom" if x == "S001" else
             ("jack" if x == "S002" else
              ("Edward" if x == "S003" else
               ("Emily" if x == "S004" else "Diablo"))),
             "age": random.randint(18, 25),
             "courses": ["数学", "语文"] if x == "S001" else
             (["数学", "英语"] if x == "S002" else
              (["数学", "英语"] if x == "S003" else
               (["语文", "英语"] if x == "S004" else ["语文", "数学"]))),
             "score": {courses: random.randint(50, 100) for courses in (["数学", "语文"] if x == "S001" else
                                                                        (["数学", "英语"] if x == "S002" else
                                                                         (["数学", "英语"] if x == "S003" else
                                                                          (["语文", "英语"] if x == "S004" else
                                                                           ["语文", "数学"]))))}
             } for x in ["S001", "S002", "S003", "S004", "S005"]]
print(students)
# 2all_courses 集合：存储所有课程名称（去重）。
# 我可以直接用集合推导式生成一个存储课名的集合
all_courses = {course for student in students for course in student["courses"]}

# 4通过字典推导式统计每门课程的选修人数，结果存入字典course_counts。
# 字典的键是课程名，值是选修人数，键可以直接使用课名集合，值需要遍历学生集合，然后统计,这个值可以在推导式外面做出来，然后在推导式直接使用
num_math = 0
num_chinese = 0
num_english = 0
for student in students:
    for course in student["courses"]:
        if course == "语文":
            num_chinese += 1
        elif course == "数学":
            num_math += 1
        else:
            num_english += 1
# 有两个值，一个是课程名，是在集合里，另一个是人数，三个变量，什么形式都可以。但是字典必须是键和值。课名-人数映射。那就把俩数据存到一起

course_counts = {course: num_english if course == "英语" else (num_math if course == "数学" else num_chinese) for course
                 in all_courses}
print(course_counts)
"""
任务2：数据转换与推导式
提取信息：
用列表推导式生成所有学生姓名的列表names。
用集合推导式生成所有未通过课程（成绩<60）的学生姓名集合failed_courses。
成绩分析：
用字典推导式生成每个学生平均分的字典avg_scores（保留1位小数）。
用生成器表达式遍历学生数据，输出年龄超过22岁的学生ID。
"""
# 1
names = [student["name"] for student in students]
failed_courses = (student["name"]
                  for student in students
                  if any(score < 60 for score in student["score"].values())
                  )
# 2
print(failed_courses)
# 3
avg_scores = {
    student["name"]: round(sum(score for score in student["score"].values()) / len(student["score"]), 1)
    for student in students
}
print(avg_scores)
# 4
over_id = list(student["id"] for student in students if student["age"] > 21)
print(over_id)

"""任务3：集合与生成器操作
课程交集：
找出同时选修"数学"和"英语"的学生ID列表（用集合操作）。
高效处理：
使用生成器表达式统计所有学生的总课程数（避免内存占用）。
"""
# 1
math_stu={student["id"] for student in students for course in student["courses"] if "数学" in course}
english_stu={student["id"] for student in students for course in student["courses"] if "英语" in course}
english_math_stu=math_stu.intersection(english_stu)
print(english_math_stu)
# 2
count_course=len(all_courses)
print(count_course)

